home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / progtool / c / gcc / crssrc16.zoo / src / xconsole.c < prev   
Encoding:
C/C++ Source or Header  |  1993-03-02  |  6.2 KB  |  349 lines

  1. /* Replacement console read/write routines that allow for key
  2.    remappings */
  3. /* 
  4.  * console input/output routines.
  5.  * written by Eric R. Smith and placed in the public domain
  6.  */
  7.  
  8. /*
  9.  * BUGS: assumes all input is coming from the same place;
  10.  * this bug shows up only when keys are remapped, though.
  11.  */
  12.  
  13. #include <osbind.h>
  14.  
  15. #ifndef __MINT__
  16. #include <support.h>
  17. #include <stdlib.h>
  18. #include <ioctl.h>
  19. #include <tchars.h>
  20. #include <signal.h>
  21. #include <unixlib.h>
  22. #include <keycodes.h>
  23. #include <string.h>
  24.  
  25. #define STRDUP(x,y) if (x) free(x); x = strdup(y);
  26.  
  27. #define S_SHIFT 0x03
  28. #define S_CNTRL    0x04
  29. #define S_ALT    0x08
  30.  
  31. extern int _console_dev;    /* in main.c */
  32. int __check_signals = 0;
  33.  
  34. /* arrays to hold keyboard strings */
  35.  
  36. static char *kb_unshft[N_KEYCODES], *kb_shft[N_KEYCODES], *kb_alt[N_KEYCODES];
  37. static char *_str = NULL;
  38.  
  39. void console_set_key(keycode, regular, shifted, alted)
  40. int keycode;
  41. char *regular, *shifted, *alted;
  42. {
  43.     if (keycode < 1 || keycode >= N_KEYCODES)
  44.         return;
  45.  
  46.     if (regular) {
  47.         if (!*regular) regular = 0;
  48.         STRDUP(kb_unshft[keycode],regular);
  49.     }
  50.     if (shifted) {
  51.         if (!*shifted) shifted = 0;
  52. /* shifted function keys are a bit screwy */
  53.         if (keycode >= F_1 && keycode <= F_10) {
  54.             STRDUP(kb_shft[keycode - F_1 + 0x54],shifted);
  55.         }
  56.         else {
  57.             STRDUP(kb_shft[keycode],shifted);
  58.         }
  59.     }
  60.     if (alted) {
  61.         if (!*alted) alted = 0;
  62.         STRDUP(kb_alt[keycode],alted);
  63.     }
  64. }
  65.  
  66. #define KBUFSIZ 80
  67. #define NUMDEV    3
  68.     /* 0 == prn:, 1 == aux:, 2 == con: */
  69.  
  70. typedef struct _buffer {
  71.     short head, tail;
  72.     long  buffer[KBUFSIZ];
  73. } k_buf;
  74.  
  75. static k_buf in_buf[NUMDEV];
  76.  
  77. #define in_dev(dev) ((dev)>2 ? _console_dev : (dev))
  78.  
  79. #define IN_BUF(dev) (&in_buf[in_dev(dev)])
  80.  
  81.  
  82. /*
  83.  * what handle means:: 0-2: BIOS handle, 3: stdout, 4: stderr
  84.  */
  85. static short LOOKUP __PROTO((short handle));
  86. static long raw_in __PROTO((int dev));
  87. static long raw_instat __PROTO((int dev));
  88. void flush_key_buff __PROTO((int dev));
  89. #if 0
  90. static void raw_out __PROTO((int dev, int c));
  91. #endif
  92.  
  93. static short
  94. #ifdef __STDC__
  95. LOOKUP(short handle)
  96. #else
  97. LOOKUP(handle)
  98. short handle;
  99. #endif
  100. {
  101.     switch(handle) {
  102.     case -3:
  103.     case -2:
  104.     case -1:
  105.     case 0:
  106.         return handle + 3;
  107.     case 2:
  108.         return 4;
  109.     case 1:
  110.         if (isatty(0)) return 3;
  111.         if (isatty(2)) return 4;
  112.         /* else fall through */
  113.     default:
  114.         return _console_dev;
  115.     }
  116. }
  117.  
  118. /*
  119.  * raw i/o routines
  120.  */
  121.  
  122. static long
  123. raw_in(dev)
  124. int dev;
  125. {
  126.   if (dev < 3)
  127.     return Bconin (dev);
  128.   else if (dev == 3)
  129.     return Crawcin ();
  130.   else
  131.     return Cauxin ();
  132. }
  133.  
  134. #if 0
  135. static void
  136. raw_out(dev, c)
  137. int dev, c;
  138. {
  139.     if (dev < 3)
  140.         Bconout(dev, c);
  141.     else if (dev == 3)
  142.         Crawio(c);
  143.     else
  144.         Cauxout(c);
  145. }
  146. #endif
  147.  
  148. static long
  149. raw_instat(dev)
  150. int dev;
  151. {
  152.     return Bconstat(in_dev(dev));
  153. }
  154.  
  155. /*
  156.  * somewhat less raw i/o routines. The main difference is that these ones
  157.  * will check for pending input before doing output, to see if a signal
  158.  * needs to be raised. This is only done if __check_signals is non-zero;
  159.  * signal() should set __check_signals when the user attempts to catch
  160.  * SIGINT or SIGQUIT. We don't do this checking all the time because
  161.  * the user may be typing ahead input for another program (e.g. if this
  162.  * is a little utility of some sort) and we shouldn't steal keystrokes
  163.  * unless necessary.
  164.  */
  165.  
  166. unsigned int console_read_byte(handle)
  167. int handle;
  168. {
  169.     k_buf *p;
  170.     short i, j, dev;
  171.     unsigned scan, key, shft;
  172.     long r;
  173.  
  174.     dev = LOOKUP(handle);
  175.  
  176.     if (_str) {
  177.         if (*_str)
  178.             return *(unsigned char *)_str++;
  179.         else
  180.             _str = 0;
  181.     }
  182.  
  183.     p = IN_BUF(dev);
  184.     if ( p->head != (i = p->tail)) {
  185.         j = p->tail + 1;
  186.         if (j >= KBUFSIZ)
  187.             j = 0;
  188.         p->tail = j;
  189.         r = p->buffer[i];
  190.     }
  191.     else
  192.         r = raw_in(dev);
  193.  
  194.     scan = (r & 0x00ff0000) >> 16;
  195.     key = r & 0x00ff;
  196.     if (scan > 0 && scan < N_KEYCODES) {
  197.         shft = Kbshift(-1);
  198.         if (shft & S_ALT)
  199.             _str = kb_alt[scan];
  200.         else if (shft & S_SHIFT)
  201.             _str = kb_shft[scan];
  202.         else if (!(shft & S_CNTRL))
  203.             _str = kb_unshft[scan];
  204.         if (_str) return *(unsigned char *)_str++;
  205.     }
  206.     return key;
  207. }
  208.  
  209. int console_input_status(handle)
  210. int handle;
  211. {
  212.     short dev;
  213.     k_buf *p;
  214.  
  215.     if (_str && *_str) return 1;
  216.     dev = LOOKUP(handle);
  217.     p = IN_BUF(dev);
  218.     return (p->head != p->tail) || raw_instat(dev);
  219. }
  220.  
  221. void
  222. console_write_byte(handle, n)
  223. int handle;
  224. int n;
  225. {
  226.     char ch;
  227.  
  228.     if (__check_signals)
  229.         flush_key_buff(handle);
  230.     ch = n;
  231.     (void)Fwrite(handle, 1L, &ch);
  232. }
  233.  
  234. void flush_key_buff(fd)  
  235. int fd;
  236.     long c;
  237.     short i, j, waiting = 0;
  238.     unsigned char ch;
  239.     k_buf *p;
  240.     short dev;
  241.     short handle;
  242.     
  243.     handle = fd;
  244.     
  245.     dev = LOOKUP(handle);
  246.     p = IN_BUF(dev);
  247.     
  248.     while (raw_instat(dev) || waiting) 
  249.     { 
  250.     c = raw_in(dev);
  251.     if (!(__ttymode & RAW)) 
  252.     {
  253.         ch = c & 0xff;
  254.         if (ch == ('S'-'@')) { waiting = 1; }
  255.         else if (ch == ('Q'-'@')) { waiting = 0; }
  256.         else if (ch == __tchars[TC_INTRC]) 
  257.         { 
  258.         p->head = p->tail;
  259.         raise(SIGINT);
  260.         }
  261.         else if (ch == __tchars[TC_QUITC]) 
  262.         { 
  263.         p->head = p->tail;
  264.         raise(SIGQUIT);
  265.         }
  266.         else if (!waiting) 
  267.         { 
  268.         i = p->head;
  269.         j = i + 1;
  270.         if (j >= KBUFSIZ) j = 0;
  271.         if (j != p->tail) 
  272.         { 
  273.             p->buffer[i] = c;
  274.             p->head = j;
  275.         }
  276.         }
  277.     }
  278.     }
  279. }
  280.  
  281. #else  /* __MINT__ */
  282.  
  283. /* a rough approximation for console_set_key using MiNT's
  284.  * XKEY ioctl
  285.  */
  286.  
  287. #include <ioctl.h>
  288. #include <keycodes.h>
  289. #include <string.h>
  290.  
  291. static struct DEFS {
  292.     int kcode, reg, shift;
  293. } codes[] = {
  294. { CURS_UP, 20, 28 },
  295. { CURS_DN, 21, 29 },
  296. { CURS_RT, 22, 30 },
  297. { CURS_LF, 23, 31 },
  298. { K_HELP, 24, 0 },
  299. { K_UNDO, 25, 0 },
  300. { K_INS, 26, 0 },
  301. { K_HOME, 27, 0 },
  302. { 0, 0, 0 }
  303. };
  304.  
  305. void
  306. console_set_key(keycode, regular, shifted, alted)
  307. int keycode;
  308. char *regular, *shifted, *alted;
  309. {
  310.     struct Xkey {
  311.         short xk_num;
  312.         char xk_def[8];
  313.     } xk;
  314.     int i;
  315.  
  316.     xk.xk_def[7] = 0;
  317.     if (keycode >= F_1 && keycode <= F_10) {
  318.         if (regular) {
  319.             xk.xk_num = keycode - F_1;
  320.             strncpy(xk.xk_def, regular, 7);
  321.             ioctl(0, TIOCSXKEY, &xk);
  322.         }
  323.         if (shifted) {
  324.             xk.xk_num = keycode - F_1 + 10;
  325.             strncpy(xk.xk_def, regular, 7);
  326.             ioctl(0, TIOCSXKEY, &xk);
  327.         }
  328.         return;
  329.     }
  330.     for (i = 0; codes[i].kcode; i++) {
  331.         if(keycode == codes[i].kcode) {
  332.             if (regular) {
  333.                 xk.xk_num = codes[i].reg;
  334.                 strncpy(xk.xk_def, regular, 7);
  335.                 ioctl(0, TIOCSXKEY, &xk);
  336.             }
  337.             if (shifted && codes[i].shift) {
  338.                 xk.xk_num = codes[i].shift;
  339.                 strncpy(xk.xk_def, shifted, 7);
  340.                 ioctl(0, TIOCSXKEY, &xk);
  341.             }
  342.             return;
  343.         }
  344.     }
  345. }
  346.  
  347. #endif /* __MINT__ */
  348.